define(
   [
      'dojo/_base/declare',
      'dojo/_base/lang',
      'dojo/data/ItemFileWriteStore'
   ],
   function(declare, lang, ItemFileWriteStore)
   {
      return declare([ItemFileWriteStore],
      {
         mIdParameterName: 'Id',
         constructor: function(args)
         {
            dojo.safeMixin(this, args);
         },
         postscript: function(args)
         {
            this.inherited(arguments);
      
            this.mOriginalItems  = [];
            this.mPendingList    = {deletedItems: [], newItems: []};
            this.repopulateOriginalList();
      
            dojo.connect(this, "onNew", this, function(pItem)
            {
               // remove from pending new and delete lists
               delete this._pending._deletedItems[pItem[this.mIdParameterName][0]];
               delete this._pending._newItems[pItem[this.mIdParameterName][0]];
      
               var inOriginalList = this.itemInOriginalList(pItem);
               var inDeletedList = this.mPendingList.deletedItems[pItem[this.mIdParameterName][0]] != undefined;
               if(!inOriginalList)
                  this.mPendingList.newItems[pItem[this.mIdParameterName][0]] = pItem;
               if(inDeletedList)
                  delete this.mPendingList.deletedItems[pItem[this.mIdParameterName][0]];
            });
            dojo.connect(this, "onDelete", this, function(pItem)
            {
               // remove from pending new and delete lists
               delete this._pending._deletedItems[pItem[this.mIdParameterName][0]];
               delete this._pending._newItems[pItem[this.mIdParameterName][0]];
      
               var inOriginalList = this.itemInOriginalList(pItem);
               var inNewList = this.mPendingList.newItems[pItem[this.mIdParameterName][0]] != undefined;
               if(inOriginalList)
                  this.mPendingList.deletedItems[pItem[this.mIdParameterName][0]] = pItem;
               if(inNewList)
                  delete this.mPendingList.newItems[pItem[this.mIdParameterName][0]];
            });
         },
         itemInOriginalList: function(pItem)
         {
            var inList = false;
            dojo.forEach(this.mOriginalItems, function(pOriginalItem, i)
            {
               if(pOriginalItem[this.mIdParameterName][0] == pItem[this.mIdParameterName][0])
               {
                  inList = true;
                  return;
               }
            }, this);
            return inList;
         },
         cloneItem: function(pItem)
         {
            var newItem = {};
            dojo.forEach(this.getAttributes(pItem), function(attributeName, i)
            {
               if(attributeName.substring(0, 2) == '__')
                  return;
      
               var attributeValue = this.getValue(pItem, attributeName, '');
               newItem[attributeName] = attributeValue;
            }, this);
            return newItem;
         },
         prepareItemList: function(list)
         {
            var items = [];
            dojo.forEach(list, function(item, i)
            {
               var newItem = this.cloneItem(item);
               items.push(newItem);
            }, this);
            return items;
         },
         repopulateOriginalList: function(onErrorCallback)
         {
            this.fetch({
               onComplete: function(items, request){
                  request.store.mOriginalItems = items;
               },
               onError: onErrorCallback
            });
         },
         save: function()
         {
            this.inherited(arguments);
            this.repopulateOriginalList();
         },
         getNewAndDeleteList: function()
         {
            var newItems = [];
            var asInt = 0;
            var propertyName = null;
            for(propertyName in this.mPendingList.newItems)
            {
               if(!this.mPendingList.newItems.hasOwnProperty(propertyName))
                  continue;

               asInt = parseInt(propertyName.replace(/^[0]+/g,""), 10);
               if(!isNaN(asInt))
                  newItems.push(asInt);
            }
            var deletedItems = [];
            for(propertyName in this.mPendingList.deletedItems)
            {
               if(!this.mPendingList.deletedItems.hasOwnProperty(propertyName))
                  continue;

               asInt = parseInt(propertyName.replace(/^[0]+/g,""), 10);
               if(!isNaN(asInt))
                  deletedItems.push(asInt);
            }
            return {
               'newItems'     : newItems,
               'deletedItems' : deletedItems
            };
         }
      
      });
   }
);
